import { Injectable } from '@angular/core';
import {Actions, ofType, Effect} from '@ngrx/effects';
import { Observable, of , pipe} from 'rxjs';
import { Router} from '@angular/router';
import * as actions from '../actions/task.action';
import {
    LoadAction,
    AddAction,
    UpdateAction,
    DeleteAction,
    CompleteAction,
    MoveAction,
    MoveALLAction,
} from '../actions/task.action';
import { Action, Store , select} from '@ngrx/store';
import * as fromRoot from '../reducers';
import { switchMap, map, catchError , tap, withLatestFrom} from 'rxjs/operators';
import { Task } from '../domain';
import { TaskService } from '../services/task.service';
@Injectable()
export class TaskEffects {
    @Effect()
    loadTasks$:Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.LOAD),
        map((a: LoadAction) => a.payload),
        switchMap(taskLists => this.taskService.getByLists(taskLists).pipe(
            map(tasks => new actions.LoadsuccessAction(tasks)),
            catchError(err => of(new actions.LoadFailAction(JSON.stringify(err)))
            )
        ))
    );
    @Effect()
    addTasks$: Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.ADD),
        map((a: AddAction) => a.payload),
        switchMap((task) => this.taskService.add(task).pipe(
            map(t => new actions.AddSuccessAction(t)),
            catchError(err => of(new actions.AddFailAction(err)))
        )),
    );
    @Effect()
    updateTasks$: Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.UPDATE),
        map((a: UpdateAction) => a.payload),
        switchMap(task => this.taskService.update(task).pipe(
            map(t => new actions.UpdateSuccessAction(t)),
            catchError( err => of(new actions.UpdateFailAction(err)))
        ))
    );
    @Effect()
    delTasks$: Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.DELETE),
        map((a: DeleteAction) => a.payload),
        switchMap(task => this.taskService.del(task).pipe(
            map(t => new actions.DeletesuccessAction(t)),
            catchError(err =>  of(new actions.DeleteFailAction(err)))
        ))
    );
    @Effect()
    complete$: Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.COMPLETE),
        map((a: CompleteAction) => a.payload),
        switchMap(task => this.taskService.complete(task).pipe(
            map(t => new actions.CompleteSuccessAction(t)),
            catchError(err =>  of(new actions.CompleteFailAction(err)))
        ))
    );
    @Effect()
    move$: Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.MOVE),
        map((a: MoveAction) => a.payload),
        switchMap(({taskId, taskListId}) => this.taskService.move(taskId, taskListId).pipe(
            map(task => new actions.MoveSuccessAction(task)),
            catchError(err =>  of(new actions.MoveFailAction(err)))
        ))
    );
    @Effect()
    moveAll$: Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.MOVE_ALL),
        map((a: MoveALLAction) => a.payload),
        switchMap(({srcListId , targetListId}) => this.taskService.moveAll(srcListId, targetListId).pipe(
            map(tasks => new actions.MoveALLSuccessAction(tasks)),
            catchError(err =>  of(new actions.MoveFailAction(err)))
        ))
    );
    constructor(
        public actions$: Actions,
        public taskService: TaskService,
        public store$: Store<fromRoot.State>,
        public router: Router
      ) {}
}
